/** 
 * @Description: 图片标注编辑器类，用于在Cesium场景中添加、编辑、移动、旋转和缩放图片标注
 * @Author: 程前
 * @Date: 2024-12-05 15:15:15
 * @LastEditors: 程前
 * @LastEditTime: 2025-01-20 16:28:49
 */

import {
    Viewer,
    Entity,
    ScreenSpaceEventHandler,
    Cartesian2,
    HeightReference,
    VerticalOrigin,
    HorizontalOrigin,
    Cartesian3,
    defined,
    ScreenSpaceEventType,
    CallbackProperty,
    Math as CesiumMath,
    LabelStyle,
    ImageMaterialProperty,
    Transforms,
    Matrix3,
    Matrix4,
    Color,
    ConstantProperty,
    PolygonHierarchy,
    EntityCollection
} from "cesium"
import { hexToRGBA, setEventByHandler, enableCameraControl, disableCameraControl, transConstantPositionProperty, removeEventByHandler } from "@/utils"
import { useCesiumEditStore } from "@/store/modules/cesium-edit";
import { ImageConfig, VectorConfig } from "@/types/pinia/cesium-edit";
import { ConstantPositionProperty } from "cesium";
import { watch, watchEffect } from 'vue'


// 扩展Entity接口
declare module 'cesium' {
    interface Entity {
        pointType?: 'scale' | 'resize' | 'move' | 'rotate';
        pointIndex?: number;
    }
}

// 实体属性接口
interface MapImageEntity {
    id: string;
    image: string;
    position: Cartesian3;
    // 非贴地模式的宽高
    billboardWidth: number;
    billboardHeight: number;
    // 贴地模式的宽高
    polygonWidth: number;
    polygonHeight: number;
    rotation: number;
    isClampToGround: boolean;
    polygonPositions: Cartesian3[];
}

export default class ImagePlotting {
    // 基础属性
    private viewer: Viewer;
    private handler: ScreenSpaceEventHandler;
    private selectedPoint: Entity | null = null;
    private imageEntity: Entity | null = null;
    private controlPoints: Entity[] = [];
    private groundControlPoints: Entity[] = [];
    private rotation: number = 0;
    private startMousePosition: Cartesian2 | null = null;
    private image: string | null = null;
    private billboardWidth: number = 100; // 非贴地初始宽度(米)
    private billboardHeight: number = 100; // 非贴地初始高度(米)
    private polygonWidth: number = 1000; // 贴地初始宽度(米)
    private polygonHeight: number = 1000; // 贴地初始高度(米)
    private lastRotation: number = 0;
    private startAngle: number = 0;
    private imgMinWidth: number = 20; // 最小宽度（米）
    private imgMinHeight: number = 20; // 最小高度（米）
    private polygonPositions: Cartesian3[] = []; // 多边形顶点位置
    private entityProperties: Map<Entity, MapImageEntity> = new Map();
    private labelOptions: Entity.ConstructorOptions['label'] = {
        text: '测试文本',
        font: '22px Microsoft YaHei',
        fillColor: Color.WHITE,
        outlineWidth: 0,
        style: LabelStyle.FILL_AND_OUTLINE,
        verticalOrigin: VerticalOrigin.BOTTOM,
        horizontalOrigin: HorizontalOrigin.CENTER,
        scale: 1.0,
        disableDepthTestDistance: Number.POSITIVE_INFINITY,
    }
    private currentConfig: ImageConfig & VectorConfig;
    private cesiumEditStore = useCesiumEditStore()
    private watchList: Function[] = []


    constructor(viewer: Viewer, handler: ScreenSpaceEventHandler) {
        this.viewer = viewer;
        this.handler = handler
        this.image = this.cesiumEditStore.plotting.src

        this.currentConfig = this.cesiumEditStore.plotting.type === 'image'
            ? { ...this.cesiumEditStore.plotting.imageConfig }
            : { ...this.cesiumEditStore.plotting.vectorConfig };

        // 使用 requestAnimationFrame 进行节流
        let rafId: number | null = null;
        let lastUpdateTime = 0;
        const minUpdateInterval = 100; // 最小更新时间

        this.viewer.camera.changed.addEventListener(() => {
            const currentTime = Date.now();
            if (currentTime - lastUpdateTime < minUpdateInterval) {
                if (rafId !== null) {
                    cancelAnimationFrame(rafId);
                }
                rafId = requestAnimationFrame(() => {
                    if (this.imageEntity) {
                        const position = this.imageEntity.position.getValue();
                        if (position) {
                            this.updateControlPointsPositions(position);
                        }
                    }
                    lastUpdateTime = Date.now();
                    rafId = null;
                });
                return;
            }

            if (this.imageEntity) {
                const position = this.imageEntity.position.getValue();
                if (position) {
                    this.updateControlPointsPositions(position);
                }
            }
            lastUpdateTime = currentTime;
        });
    }

    /**
     * 初始化事件监听
     */
    initEvents(): void {
        // 移除之前的事件监听器
        this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK);
        const leftClick = async (event: any) => {
            const position = this.viewer.scene.camera.pickEllipsoid(
                event.position,
                this.viewer.scene.globe.ellipsoid
            );

            if (position) {
                // 获取最新配置
                this.currentConfig = this.cesiumEditStore.plotting.type === 'image' ? this.cesiumEditStore.plotting.imageConfig : this.cesiumEditStore.plotting.vectorConfig
                // 监听配置变化
                this.initWatcher()
                this.imageEntity && this.stopEditing()
                const entities = await this.add(this.image, position);
                this.startEditing(entities);
            }
        }

        setEventByHandler(this.handler, leftClick, ScreenSpaceEventType.LEFT_CLICK);
    }

    /**
     * 在指定位置添加图片标注
     * @param imgSrc 图片路径
     * @param position 添加位置
     * @returns 返回创建的图片实体
     */
    async add(imgSrc: string, position: Cartesian3) {
        if (!imgSrc) return null;
        const isImage = this.cesiumEditStore.plotting.type === 'image'
        this.setLabelOptions()

        // 初始化属性
        // 处理svg颜色
        this.image = isImage ? imgSrc : await this.replaceSvgColor(imgSrc);
        // 添加标注
        const entity = this.addImage(this.image, position)

        // 保存当前编辑实体的属性
        this.entityProperties.set(entity, {
            id: entity.id,
            image: this.image,
            position,
            billboardWidth: this.billboardWidth,
            billboardHeight: this.billboardHeight,
            polygonWidth: this.polygonWidth,
            polygonHeight: this.polygonHeight,
            rotation: this.currentConfig.rotation,
            isClampToGround: this.currentConfig.isClampToGround,
            polygonPositions: this.currentConfig.isClampToGround ? [...this.polygonPositions] : []
        });
        return entity;
    }

    /**
     * 添加标注
     * @param imagePath 资源路径
     * @param position  中心点
     */
    addImage(imagePath: string, position: Cartesian3): Entity {
        this.polygonPositions = this.calculatePolygonPositions(position, this.polygonWidth, this.polygonHeight);
        const cesiumEditStore = useCesiumEditStore()
        let imageEntity: Entity;
        imageEntity = this.viewer.entities.add({
            position,
            billboard: {
                show: new CallbackProperty(() => !this.currentConfig.isClampToGround, false),
                image: imagePath,
                width: this.billboardWidth,
                height: this.billboardHeight,
                verticalOrigin: VerticalOrigin.CENTER,
                horizontalOrigin: HorizontalOrigin.CENTER,
                rotation: new CallbackProperty(() => {
                    if (this.imageEntity && !this.currentConfig.isClampToGround) {
                        this.updateControlPointsPositions(this.imageEntity!.position.getValue());
                    }
                    return CesiumMath.toRadians(-this.currentConfig.rotation)
                }, false),
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
            },
            polygon: {
                show: new CallbackProperty(() => this.currentConfig.isClampToGround, false),
                hierarchy: new PolygonHierarchy(this.polygonPositions),
                material: new ImageMaterialProperty({
                    image: imagePath,
                    repeat: new Cartesian2(1, 1),
                    color: cesiumEditStore.plotting.type === 'image' ? Color.WHITE : Color.fromCssColorString(cesiumEditStore.plotting.vectorConfig.color)
                }),
                stRotation: new CallbackProperty(() => {
                    if (this.imageEntity && this.currentConfig.isClampToGround) {
                        this.updateControlPointsPositions(this.imageEntity!.position.getValue());
                        this.updateHirarchy()
                    }
                    return CesiumMath.toRadians(this.currentConfig.rotation)
                }, false),
                // heightReference: HeightReference.CLAMP_TO_GROUND,
                // zIndex: 1,
                perPositionHeight: false,
                closeTop: true,
                closeBottom: false
            },
            label: {
                ...this.labelOptions,
                pixelOffset: new Cartesian2(this.billboardWidth * 0.5, 10),
            }
        });
        return imageEntity
    }

    // /**
    //  * 添加贴地标注
    //  * @param imagePath 资源路径
    //  * @param position  中心点
    //  * @param initialPositions 多边形坐标 
    //  * @returns 
    //  */
    // addGroundImage(imagePath: string, position: Cartesian3, initialPositions: Cartesian3[]): Entity {
    //     const cesiumEditStore = useCesiumEditStore()
    //     const imageEntity = this.viewer.entities.add({
    //         position,
    //         polygon: {
    //             hierarchy: new PolygonHierarchy(initialPositions),
    //             material: new ImageMaterialProperty({
    //                 image: imagePath,
    //                 repeat: new Cartesian2(1, 1),
    //                 color: cesiumEditStore.plotting.type === 'image' ? Color.WHITE : Color.fromCssColorString(cesiumEditStore.plotting.vectorConfig.color)
    //             }),
    //             heightReference: HeightReference.CLAMP_TO_GROUND,
    //             stRotation: new CallbackProperty(() => {
    //                 if (this.imageEntity) {
    //                     this.updateControlPointsPositions(this.imageEntity!.position.getValue());
    //                     this.updateHirarchy()
    //                 }
    //                 return CesiumMath.toRadians(this.currentConfig.rotation)
    //             }, false),
    //             zIndex: 1,
    //             perPositionHeight: false,
    //             closeTop: true,
    //             closeBottom: false
    //         },
    //         label: {
    //             ...this.labelOptions,
    //             eyeOffset: new Cartesian3(this.imageWidth * 0.3, -5, 0),
    //         }
    //     });

    //     return imageEntity
    // }

    /**
     * 开始编辑图片
     * @param entity 要编辑的图片实体
     */
    startEditing(entity: Entity): void {
        // 设置新的编辑实体
        this.imageEntity = entity;

        // 清空维护属性
        this.selectedPoint = null;
        this.startMousePosition = null;
        this.polygonPositions = []

        const position = entity.position.getValue();
        if (position) {
            this.createControlPoints(position);
            this.updateControlPointsPositions(position);
            this.addInteraction();
        }
    }

    /**
     * 停止编辑
     */
    stopEditing(): void {
        if (!this.imageEntity) return;

        // 获取当前实体是否为贴地模式
        const props = this.entityProperties.get(this.imageEntity);

        if (!props) return;
        // 保存当前编辑实体的属性
        this.entityProperties.set(this.imageEntity, {
            id: this.imageEntity.id,
            image: this.image,
            position: this.imageEntity.position.getValue(),
            billboardWidth: props.billboardWidth,
            billboardHeight: props.billboardHeight,
            polygonWidth: props.polygonWidth,
            polygonHeight: props.polygonHeight,
            rotation: this.currentConfig.rotation,
            isClampToGround: this.currentConfig.isClampToGround,
            polygonPositions: [...this.polygonPositions]
        });

        // 修改为静态属性
        this.imageEntity.position = new ConstantPositionProperty(this.imageEntity.position.getValue());
        this.imageEntity.polygon.show = new ConstantProperty(this.currentConfig.isClampToGround);
        this.imageEntity.polygon!.hierarchy = new ConstantProperty({ positions: props.polygonPositions });
        this.imageEntity.polygon!.stRotation = new ConstantProperty(CesiumMath.toRadians(this.currentConfig.rotation));
        this.imageEntity.position = new ConstantPositionProperty(this.imageEntity.position.getValue());
        this.imageEntity.billboard.show = new ConstantProperty(!this.currentConfig.isClampToGround);
        this.imageEntity.billboard!.width = new ConstantProperty(props.billboardWidth);
        this.imageEntity.billboard!.height = new ConstantProperty(props.billboardHeight);
        this.imageEntity.billboard!.rotation = new ConstantProperty(CesiumMath.toRadians(- this.currentConfig.rotation));

        // 清理控制点及watch
        this.removeControlPoints();
        this.watchList.forEach((unWatch: Function) => unWatch());
        this.watchList = [];
        this.imageEntity = null
    }

    /**
     * 移除所有控制点
     */
    private removeControlPoints() {
        this.controlPoints.forEach((point: Entity) => {
            this.viewer.entities.remove(point);
        });
        this.controlPoints = [];
        this.groundControlPoints.forEach((point: Entity) => {
            this.viewer.entities.remove(point);
        })
        this.groundControlPoints = [];
    }

    /**
     * 创建图片的控制点
     * @param position 图片位置
     */
    private createControlPoints(position: Cartesian3): void {
        this.createGroundControlPoints();
        this.createBillboardControlPoints();

    }

    /**
     * 创建贴地控制点
     */
    private createGroundControlPoints(): void {
        const points = [
            { type: 'scale' as const, offset: [-1, -1], color: Color.BLUE },   // 左上角等比缩放点
            { type: 'scale' as const, offset: [1, -1], color: Color.BLUE },    // 右上角等比缩放点 
            { type: 'scale' as const, offset: [1, 1], color: Color.BLUE },     // 右下角等比缩放点
            { type: 'scale' as const, offset: [-1, 1], color: Color.BLUE },    // 左下角等比缩放点
            { type: 'rotate' as const, offset: [0, 1.3], color: Color.GREEN }, // 上方旋转点
            { type: 'resize' as const, offset: [0, -1], color: Color.WHITE },   // 上边缩放点
            { type: 'resize' as const, offset: [1, 0], color: Color.WHITE },    // 右边缩放点
            { type: 'resize' as const, offset: [0, 1], color: Color.WHITE },    // 下边缩放点
            { type: 'resize' as const, offset: [-1, 0], color: Color.WHITE },   // 左边缩放点
            { type: 'move' as const, offset: [0, 0], color: Color.YELLOW }      // 中心移动点
        ];

        points.forEach((point, index) => {
            const imagePos = this.imageEntity!.position.getValue();
            if (!imagePos) return false;
            const offsetX = point.offset[0] * this.polygonWidth;
            const offsetY = point.offset[1] * this.polygonHeight;
            const controlPoint = this.viewer.entities.add({
                position: this.calculateControlPointPosition(imagePos, offsetX, offsetY),
                point: {
                    show: new CallbackProperty(() => this.currentConfig.isClampToGround, false),
                    pixelSize: 8,
                    color: point.color,
                    outlineColor: Color.BLACK,
                    outlineWidth: 2,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                },
                pointType: point.type,
                pointIndex: index
            });
            this.groundControlPoints.push(controlPoint);
        });
    }

    /**
     * 创建非贴地控制点
     * @param position 
     */
    private createBillboardControlPoints(): void {
        const points = [
            { type: 'scale' as const, offset: [-1, -1] },   // 左上等比缩放点
            { type: 'scale' as const, offset: [1, -1] },    // 右上角等比缩放点 
            { type: 'scale' as const, offset: [1, 1] },     // 右下角等比缩放点
            { type: 'scale' as const, offset: [-1, 1] },    // 左下角等比缩放点
            { type: 'rotate' as const, offset: [0, -1.3] }, // 上方旋转点
            { type: 'resize' as const, offset: [0, -1] },   // 上边缩放点
            { type: 'resize' as const, offset: [1, 0] },    // 右边缩放点
            { type: 'resize' as const, offset: [0, 1] },    // 下边缩放点
            { type: 'resize' as const, offset: [-1, 0] },   // 左边缩放点
            { type: 'move' as const, offset: [0, 0] }       // 中心移动点
        ];

        points.forEach((point, index) => {
            const canvas = document.createElement('canvas');
            canvas.width = 12;
            canvas.height = 12;
            const context = canvas.getContext('2d')!;
            const color = point.type === 'scale' ? '#0000FF' :
                point.type === 'resize' ? '#FFFFFF' :
                    point.type === 'rotate' ? '#00FF00' : '#FFFF00';
            context.beginPath();
            context.arc(6, 6, 5, 0, 2 * Math.PI);
            context.fillStyle = color;
            context.fill();
            context.strokeStyle = '#000000';
            context.lineWidth = 1;
            context.stroke();

            const imagePos = this.imageEntity!.position.getValue();
            if (!imagePos) return;
            const screenCenter = this.viewer.scene.cartesianToCanvasCoordinates(imagePos);
            if (!screenCenter) return imagePos;
            const offsetX = point.offset[0] * this.billboardWidth / 2;
            const offsetY = point.offset[1] * this.billboardHeight / 2;
            const rotatedOffset = this.rotatePoint(offsetX, offsetY, 0);
            const screenPos = {
                x: screenCenter.x + rotatedOffset.x,
                y: screenCenter.y + rotatedOffset.y
            };
            const position = this.viewer.scene.camera.pickEllipsoid(
                new Cartesian2(screenPos.x, screenPos.y),
                this.viewer.scene.globe.ellipsoid
            )

            const controlPoint = this.viewer.entities.add({
                position,
                billboard: {
                    show: new CallbackProperty(() => !this.currentConfig.isClampToGround, false),
                    image: canvas,
                    verticalOrigin: VerticalOrigin.CENTER,
                    horizontalOrigin: HorizontalOrigin.CENTER,
                    scale: 1.0,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                },
                pointType: point.type,
                pointIndex: index,
            });
            this.controlPoints.push(controlPoint);
        });
    }

    /**
     * 添加交互事件处理
     */
    private addInteraction(): void {
        // 鼠标移动事件
        const mouseMove = (event: any) => {
            if (!this.selectedPoint || !this.startMousePosition) return;

            const imagePos = this.imageEntity?.position.getValue();
            if (!imagePos) return;

            switch (this.selectedPoint.pointType) {
                case 'move':
                    this.handleMove(event.endPosition);
                    break;
                case 'resize':
                    this.handleResize(event.endPosition, this.selectedPoint.pointIndex!);
                    break;
                case 'scale':
                    this.handleScale(event.endPosition);
                    break;
                case 'rotate':
                    this.handleRotate(event.endPosition);
                    break;
            }

            this.startMousePosition = event.endPosition.clone();
        }

        // 鼠标按下事件
        const leftDown = (event: any) => {
            const pickedObject = this.viewer.scene.pick(event.position);
            if (defined(pickedObject) && pickedObject.id) {
                const entity = pickedObject.id;
                if (entity.pointType) {
                    this.selectedPoint = entity;
                    this.startMousePosition = event.position.clone();

                    // 如果是旋转操作 记录开始时的角度
                    if (entity.pointType === 'rotate') {
                        const imagePos = this.imageEntity!.position.getValue();
                        const centerScreen = this.viewer.scene.cartesianToCanvasCoordinates(imagePos);
                        if (centerScreen) {
                            const vector = {
                                x: event.position.x - centerScreen.x,
                                y: event.position.y - centerScreen.y
                            };
                            this.startAngle = Math.atan2(vector.y, vector.x);
                            this.lastRotation = this.currentConfig.rotation;
                        }
                    }
                    setEventByHandler(this.handler, mouseMove, ScreenSpaceEventType.MOUSE_MOVE);
                    disableCameraControl();
                }
            }
        }
        setEventByHandler(this.handler, leftDown, ScreenSpaceEventType.LEFT_DOWN);


        // 鼠标释放事件
        const leftUp = () => {
            this.selectedPoint = null;
            this.startMousePosition = null;
            enableCameraControl();
            removeEventByHandler(this.handler, ScreenSpaceEventType.MOUSE_MOVE);
        }
        setEventByHandler(this.handler, leftUp, ScreenSpaceEventType.LEFT_UP);
    }

    /**
     * 处理图片移动
     * @param currentPosition 当前鼠标位置
     */
    private handleMove(currentPosition: Cartesian2): void {
        if (!this.imageEntity) return;

        const ray = this.viewer.camera.getPickRay(currentPosition);
        if (!ray) return;

        const newPos = this.viewer.scene.globe.pick(ray, this.viewer.scene);

        if (!newPos) return;

        const props = this.entityProperties.get(this.imageEntity);

        if (!props) return;

        // 更新实体位置
        this.imageEntity.position = new ConstantPositionProperty(newPos);

        // 更新多边形位置
        props.polygonPositions = this.calculatePolygonPositions(newPos, props.polygonWidth, props.polygonHeight);
        this.imageEntity.polygon!.hierarchy = new ConstantProperty({ positions: props.polygonPositions })

        // 保存更新后的属性
        this.entityProperties.set(this.imageEntity, props);

        // 更新控制点位置
        this.updateControlPointsPositions(newPos);
    }

    /**
     * 处理图片缩放
     * @param currentPosition 当前鼠标位置
     * @param index 控制点索引
     */
    private handleResize(currentPosition: Cartesian2, index: number): void {
        if (!this.imageEntity || !this.startMousePosition) return;

        const props = this.entityProperties.get(this.imageEntity);
        if (!props) return;

        const imagePos = this.imageEntity.position.getValue();
        const centerScreen = this.viewer.scene.cartesianToCanvasCoordinates(imagePos);
        if (!centerScreen) return;

        // 计算缩放比例
        const currentDistance = Math.sqrt(
            Math.pow(currentPosition.x - centerScreen.x, 2) +
            Math.pow(currentPosition.y - centerScreen.y, 2)
        );
        const startDistance = Math.sqrt(
            Math.pow(this.startMousePosition.x - centerScreen.x, 2) +
            Math.pow(this.startMousePosition.y - centerScreen.y, 2)
        );
        const scale = currentDistance / startDistance;

        // 根据控制点索引和模式更新宽度或高度
        if (this.currentConfig.isClampToGround) {
            if (index === 5 || index === 7) {
                props.polygonHeight = Math.max(this.imgMinHeight, props.polygonHeight * scale);
            } else if (index === 6 || index === 8) {
                props.polygonWidth = Math.max(this.imgMinWidth, props.polygonWidth * scale);
            }

            // 更新多边形位置
            props.polygonPositions = this.calculatePolygonPositions(imagePos, props.polygonWidth, props.polygonHeight);
            this.imageEntity.polygon!.hierarchy = new CallbackProperty(() => ({
                positions: props.polygonPositions
            }), false);
        } else {
            if (index === 5 || index === 7) {
                props.billboardHeight = Math.max(this.imgMinHeight, props.billboardHeight * scale);
            } else if (index === 6 || index === 8) {
                props.billboardWidth = Math.max(this.imgMinWidth, props.billboardWidth * scale);
            }

            // 更新billboard的宽高
            this.imageEntity.billboard!.width = new CallbackProperty(() => props.billboardWidth, false);
            this.imageEntity.billboard!.height = new CallbackProperty(() => props.billboardHeight, false);
        }

        // 保存更新后的属性
        this.entityProperties.set(this.imageEntity, props);

        // 更新控制点位置
        this.updateControlPointsPositions(imagePos);
    }

    /**
     * 处理图片旋转
     * @param currentPosition 当前鼠标位置
     */
    private handleRotate(currentPosition: Cartesian2): void {
        const imagePos = this.imageEntity!.position.getValue();
        const centerScreen = this.viewer.scene.cartesianToCanvasCoordinates(imagePos);
        if (!centerScreen) return;

        // 计算当前角度
        const currentVector = {
            x: currentPosition.x - centerScreen.x,
            y: currentPosition.y - centerScreen.y
        };

        const currentAngle = Math.atan2(currentVector.y, currentVector.x);

        // 计算角度差(转换为度数)
        let deltaAngle = CesiumMath.toDegrees(currentAngle - this.startAngle);

        // 确保角度差在-180到180度之间
        if (deltaAngle > 180) {
            deltaAngle -= 360;
        }
        if (deltaAngle < -180) {
            deltaAngle += 360;
        }

        // 更新旋转角度
        const props = this.entityProperties.get(this.imageEntity!);
        if (props) {
            // 计算新的旋转角度
            let newRotation = CesiumMath.toDegrees(this.lastRotation) - deltaAngle;

            // 确保最终角度0到360度之间
            while (newRotation >= 360) {
                newRotation -= 360;
            }
            while (newRotation < 0) {
                newRotation += 360;
            }

            //更新角度及多边形位置
            this.currentConfig.rotation = this.lastRotation + deltaAngle;
            if (this.currentConfig.isClampToGround && this.imageEntity) {
                this.updateHirarchy();
            }

            // 保存更新后的属性
            this.entityProperties.set(this.imageEntity!, props);
        }
    }

    /**
     * 根据最新坐标及旋转角度更新多边形位置
     */
    private updateHirarchy() {
        // 更新多边形位置
        const position = this.imageEntity.position.getValue();
        const props = this.entityProperties.get(this.imageEntity!);

        // 计算新的多边形顶点位置,考虑旋转角度
        const transform = Transforms.eastNorthUpToFixedFrame(position);
        const rotation = Matrix3.fromRotationZ(CesiumMath.toRadians(-this.currentConfig.rotation));
        const rotationMatrix = Matrix4.fromRotationTranslation(rotation);
        const modelMatrix = Matrix4.multiply(transform, rotationMatrix, new Matrix4());

        // 计算旋转后的顶点位置
        const halfWidth = props.polygonWidth / 2;
        const halfHeight = props.polygonHeight / 2;
        const corners = [
            new Cartesian3(-halfWidth, -halfHeight, 0),
            new Cartesian3(halfWidth, -halfHeight, 0),
            new Cartesian3(halfWidth, halfHeight, 0),
            new Cartesian3(-halfWidth, halfHeight, 0)
        ];

        const rotatedPositions: Cartesian3[] = [];
        const worldPos = new Cartesian3();
        corners.forEach(localPosition => {
            Matrix4.multiplyByPoint(modelMatrix, localPosition, worldPos);
            rotatedPositions.push(Cartesian3.clone(worldPos));
        });

        // 更新多边形位置
        props.polygonPositions = rotatedPositions;
        this.imageEntity.polygon!.hierarchy = new ConstantProperty({
            positions: props.polygonPositions
        });
    }

    /**
     * 更新控制点位置
     * @param position 图片新位置
     */
    private updateControlPointsPositions(position: Cartesian3): void {
        if (!position || !this.imageEntity || !this.controlPoints.length) return;

        // 缓存当前实体属性
        const props = this.entityProperties.get(this.imageEntity);
        if (!props) return;

        // 预先计算变换矩阵
        const transform = Transforms.eastNorthUpToFixedFrame(position);
        const rotation = Matrix3.fromRotationZ(CesiumMath.toRadians(-this.currentConfig.rotation));
        const rotationMatrix = Matrix4.fromRotationTranslation(rotation);
        const modelMatrix = Matrix4.multiply(transform, rotationMatrix, new Matrix4());
        if (this.currentConfig.isClampToGround) {
            // 更新贴地模式控制点位置
            this.groundControlPoints.forEach((point, index) => {
                const offset = this.getControlPointOffset(index);
                // es参考系取负 和非贴地方向一致
                const localPosition = new Cartesian3(-offset[0], -offset[1], 0);

                // 计算世界坐标
                const worldPos = Matrix4.multiplyByPoint(
                    modelMatrix,
                    localPosition,
                    new Cartesian3()
                );

                // 使用直接赋值而不是 CallbackProperty
                point.position = transConstantPositionProperty(worldPos);

            });
        } else {
            // 缓存屏幕中心点

            // 更新非贴地模式控制点位置
            const screenCenter = this.viewer.scene.cartesianToCanvasCoordinates(position);
            if (!screenCenter) return;

            this.controlPoints.forEach((point, index) => {
                const offset = this.getControlPointOffset(index);
                const rotatedOffset = this.rotatePoint(offset[0], offset[1], CesiumMath.toRadians(this.currentConfig.rotation));
                const screenPos = {
                    x: screenCenter.x + rotatedOffset.x,
                    y: screenCenter.y + rotatedOffset.y
                };

                const worldPos = this.viewer.scene.camera.pickEllipsoid(
                    new Cartesian2(screenPos.x, screenPos.y),
                    this.viewer.scene.globe.ellipsoid
                );
                point.position = transConstantPositionProperty(worldPos);
            });
        }
    }

    /**
     * 获取控制点偏移量
     * @param index 控制点索引
     * @returns 偏移量标[x, y]
     */
    private getControlPointOffset(index: number): [number, number] {
        const offsets: [number, number][] = [
            [-1, -1],   // 0: 左上角等比缩放点
            [1, -1],    // 1: 右上角等比缩放点
            [1, 1],     // 2: 右下角等比缩放点
            [-1, 1],    // 3: 左下角等比缩放点
            [0, -1.3],  // 4: 上方旋转点
            [0, -1],    // 5: 上边缩放点
            [1, 0],     // 6: 右边缩放点
            [0, 1],     // 7: 下边缩放点
            [-1, 0],    // 8: 左边缩放点
            [0, 0]      // 9: 中心移动点
        ];

        if (index >= 0 && index < offsets.length) {
            // 使用当前编辑实体的属性
            const props = this.imageEntity ? this.entityProperties.get(this.imageEntity) : null;
            const width = this.currentConfig.isClampToGround ? props.polygonWidth : props.billboardWidth
            const height = this.currentConfig.isClampToGround ? props.polygonHeight : props.billboardHeight
            if (props) {
                return [
                    offsets[index][0] * width / 2,
                    offsets[index][1] * height / 2
                ];
            }
        }

        return [0, 0];
    }

    /**
     * 计算点的旋转后位置
     * @param x x坐标
     * @param y y坐标
     * @param angle 旋转角度
     * @returns 旋转后的坐标{x, y}
     */
    private rotatePoint(x: number, y: number, angle: number): { x: number; y: number } {
        const cos = Math.cos(angle);
        const sin = Math.sin(angle);
        return {
            x: x * cos - y * sin,
            y: x * sin + y * cos
        };
    }

    /**
     * 设置图片路径
     * @param imgSrc 图片路径
     */
    public setImagePath(imgSrc: string): void {
        this.image = imgSrc;
    }

    /**
     * 等比缩放
     * @param currentPosition 当前鼠标位置
     */
    private handleScale(currentPosition: Cartesian2): void {
        if (!this.imageEntity || !this.startMousePosition) return;

        const props = this.entityProperties.get(this.imageEntity);
        if (!props) return;

        const imagePos = this.imageEntity.position.getValue();
        const centerScreen = this.viewer.scene.cartesianToCanvasCoordinates(imagePos);
        if (!centerScreen) return;

        // 计算缩放比例
        const currentDistance = Math.sqrt(
            Math.pow(currentPosition.x - centerScreen.x, 2) +
            Math.pow(currentPosition.y - centerScreen.y, 2)
        );
        const startDistance = Math.sqrt(
            Math.pow(this.startMousePosition.x - centerScreen.x, 2) +
            Math.pow(this.startMousePosition.y - centerScreen.y, 2)
        );
        const scale = currentDistance / startDistance;

        if (this.currentConfig.isClampToGround) {
            // 更新贴地模式的宽高
            const newWidth = Math.max(this.imgMinWidth, props.polygonWidth * scale);
            const newHeight = Math.max(this.imgMinHeight, props.polygonHeight * scale);
            props.polygonWidth = newWidth;
            props.polygonHeight = newHeight;

            // 更新多边形位置
            props.polygonPositions = this.calculatePolygonPositions(imagePos, newWidth, newHeight);
            this.imageEntity.polygon!.hierarchy = new CallbackProperty(() => ({
                positions: props.polygonPositions
            }), false);
        } else {
            // 更新非贴地模式的宽高
            const newWidth = Math.max(this.imgMinWidth, props.billboardWidth * scale);
            const newHeight = Math.max(this.imgMinHeight, props.billboardHeight * scale);
            props.billboardWidth = newWidth;
            props.billboardHeight = newHeight;

            // 更新billboard的宽高
            this.imageEntity.billboard!.width = new CallbackProperty(() => newWidth, false);
            this.imageEntity.billboard!.height = new CallbackProperty(() => newHeight, false);
        }

        // 保存更新后的属性
        this.entityProperties.set(this.imageEntity, props);

        // 更新控制点位置
        this.updateControlPointsPositions(imagePos);
    }

    /**
     * 计算多边形顶点位置-根据中心点及相对位置计算旋转及Cartesian3坐标数组
     * @param center 多边形的中心点
     * @param width 多边形的宽度
     * @param height 多边的高度
     * @returns 多边形顶点位置
     */
    private calculatePolygonPositions(center: Cartesian3, width: number, height: number): Cartesian3[] {
        try {
            const positions: Cartesian3[] = [];
            const halfWidth = width / 2;
            const halfHeight = height / 2;

            // 缓存实体属性
            const props = this.imageEntity
                ? this.entityProperties.get(this.imageEntity)
                : null;
            const entityRotation = props?.rotation || this.rotation;

            // 预先计算变换矩阵
            const transform = Transforms.eastNorthUpToFixedFrame(center);
            const rotation = Matrix3.fromRotationZ(entityRotation);
            const rotationMatrix = Matrix4.fromRotationTranslation(rotation);
            const modelMatrix = Matrix4.multiply(transform, rotationMatrix, new Matrix4());

            // 使用预先分配的数组
            const corners = [
                new Cartesian3(-halfWidth, -halfHeight, 0),
                new Cartesian3(halfWidth, -halfHeight, 0),
                new Cartesian3(halfWidth, halfHeight, 0),
                new Cartesian3(-halfWidth, halfHeight, 0)
            ];

            // 重用 Cartesian3 实例
            const worldPos = new Cartesian3();
            corners.forEach(localPosition => {
                Matrix4.multiplyByPoint(modelMatrix, localPosition, worldPos);
                positions.push(Cartesian3.clone(worldPos));
            });

            return positions;
        } catch (error) {
            console.error('计算多边形顶点位置失败:', error);
            return [];
        }
    }

    /**
     * 计算控制点位置
     * @param center 多边形的中心点
     * @param offsetX x偏移量
     * @param offsetY y偏移量
     * @returns 控制点的世界坐标
     */
    private calculateControlPointPosition(center: Cartesian3, offsetX: number, offsetY: number): Cartesian3 {
        try {
            const transform = Transforms.eastNorthUpToFixedFrame(center);

            // 使用实体特定的旋转角度
            const entityRotation = this.imageEntity
                ? this.entityProperties.get(this.imageEntity)?.rotation || 0
                : this.rotation;

            // 创建旋转矩阵
            const rotation = Matrix3.fromRotationZ(entityRotation);
            const rotationMatrix = Matrix4.fromRotationTranslation(rotation);

            // 组合变换矩阵
            const modelMatrix = Matrix4.multiply(transform, rotationMatrix, new Matrix4());

            // 在局部坐标系中创建点，不需要再乘以高，因为 getControlPointOffset 已经处理了
            const localPosition = new Cartesian3(offsetX, offsetY, 0);

            // 应用组合变换
            const worldPos = Matrix4.multiplyByPoint(
                modelMatrix,
                localPosition,
                new Cartesian3()
            );

            // 确保回的位置有效
            if (!worldPos || !defined(worldPos.x) || !defined(worldPos.y) || !defined(worldPos.z)) {
                console.warn('无效的控制点位置，使用中心点位置');
                return center;
            }

            return worldPos;
        } catch (error) {
            console.error('计算控制点位置失败:', error);
            return center;
        }
    }

    /**
     * 替换svg图片颜色
     */
    private async replaceSvgColor(imgSrc: string): Promise<string> {
        const res = await fetch(imgSrc);
        const svgData = await res.text();
        const color = this.currentConfig.color;
        const updatedSvg = svgData.replace("#000000", color);
        const svgBlob = new Blob([updatedSvg], { type: "image/svg+xml" });
        return URL.createObjectURL(svgBlob)
    }

    /**
     * 设置标签配置属性
     */
    public setLabelOptions(): void {
        this.labelOptions.text = this.currentConfig.name
        this.labelOptions.fillColor = Color.fromCssColorString(this.currentConfig.labelColor)
    }

    /**
     * 监听配置变化
     */
    private initWatcher(): void {
        const labelUnWatch = watchEffect(() => {
            if (this.imageEntity) {
                this.updateLabel(this.currentConfig.name, this.currentConfig.labelColor)
            }
        })
        this.watchList.push(labelUnWatch)
        const colorUnWatch = watch(() => this.currentConfig.color, (newVal: string) => {
            if (!this.imageEntity) return;
            this.updateImageColor()
        })
        this.watchList.push(colorUnWatch)
    }

    /**
     * 更新标签属性
     */
    private updateLabel(text: string, color: string): void {
        this.setLabelOptions()
        this.imageEntity.label.text = new ConstantProperty(text)
        this.imageEntity.label.fillColor = new ConstantProperty(Color.fromCssColorString(color))
    }

    /**
     * 更新矢量图片颜色
     */
    private async updateImageColor() {
        const isImage = this.cesiumEditStore.plotting.type === 'image';
        if (isImage) return false;
        this.image = await this.replaceSvgColor(this.image)
        if (this.currentConfig.isClampToGround) {
            this.imageEntity.polygon.material = new ImageMaterialProperty({
                image: this.image,
                repeat: new Cartesian2(1, 1),
                color: Color.fromCssColorString((this.currentConfig as VectorConfig).color)
            })
        } else {
            this.imageEntity.billboard.image = new ConstantProperty(this.image)
        }

    }


    /**
* 销毁编辑器，清理所有实体和事件监听
*/
    public destroy(): void {
        this.viewer.camera.changed.removeEventListener(this.updateControlPointsPositions);
        this.stopEditing();
        if (this.handler) {
            this.handler.destroy();
        }
    }
}
